package com.winit.feature.manager;

import com.winit.common.base.BaseController;
import com.winit.common.base.ExecuteResult;
import com.winit.common.base.StandardFeedBackInfo;
import com.winit.common.constants.IdTag;
import com.winit.common.util.Constants;
import com.winit.common.util.treeUtils.BaseTree;
import com.winit.common.util.treeUtils.TreeUtil;
import com.winit.commons.util.SeqGenerate;
import com.winit.config.model.Config;
import com.winit.config.service.IConfigService;
import com.winit.feature.model.Feature;
import com.winit.feature.model.FeatureReq;
import com.winit.feature.model.FeatureReqId;
import com.winit.feature.repository.FeatureOperations;
import com.winit.feature.repository.FeatureRepository;
import com.winit.feature.repository.FeatureReqRepository;
import com.winit.indexing.model.Indexing;
import com.winit.indexing.model.IndexingId;
import com.winit.indexing.service.IIdexingService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.cassandra.core.CassandraOperations;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class FeatureManager_bak {

    private static Logger logger = LoggerFactory.getLogger(FeatureManager_bak.class);

    @Autowired
    private FeatureRepository featureRepository;
    @Autowired
    private FeatureOperations featureOperations;

    @Autowired
    private CassandraOperations cassandraOperations;
    @Autowired
    private IConfigService configService;
    @Autowired
    private IIdexingService indexingService;
    @Autowired
    private FeatureReqRepository featureReqRepository;

    /**
     * @NotUsed
     * @param feature
     * @return
     */
    @Deprecated
    public ExecuteResult saveFeature(Feature feature) {
        if (feature.getId() == null) {
            logger.info("feature id not found, add will be executed.");
            return this.addFeature(feature);
        }
        Feature existOne = this.featureRepository.findOne(feature.getId());
        ExecuteResult executeResult = null;
        if (null == existOne) {
            executeResult = new ExecuteResult();
            executeResult.setCode(StandardFeedBackInfo.REQUEST_ERROR);
            executeResult.setMsg("no feature node found for id:" + feature.getId());
        }
        if ("DELETE".equalsIgnoreCase(feature.getStatus())) {//删除操作
            return this.deleteFeature(feature);
        }
        //更新操作
        return this.updateFeature(feature);
    }

    public ExecuteResult featureOccupy(String reqId, String id){
        Feature feature = this.featureRepository.findOne(id);
        ExecuteResult tempRs = this.getFeature(0, feature.getSys(), feature.getId(), null, true, null);
        Feature existsOneWithAttr = (Feature) ((BaseTree) ((List)tempRs.getData()).get(0)).getMetaData();
        Feature update  = new Feature();
        update.setId(id);
        update.setReqId(reqId);
        update.setAttr(existsOneWithAttr.getAttr());
        return this.updateFeatureConfig(update);
    }
    public ExecuteResult updateFeatureConfig(Feature feature) {
        ExecuteResult executeResult = new ExecuteResult();

        if (feature.getId() == null) {
            String msg = "id为空，更新终止";
            logger.error(msg);
            executeResult.setCode(BaseController.REQUEST_ERROR);
            executeResult.setMsg(msg);
            return executeResult;
        }
        String reqId = feature.getReqId();
        if (StringUtils.isEmpty(reqId)) {
            String msg = "reqId为空，更新终止.";
            logger.error(msg);
            executeResult.setCode(BaseController.REQUEST_ERROR);
            executeResult.setMsg(msg);
            return executeResult;
        }
        if ("-1".equals(reqId)){
            String msg = "reqId为-1，该方法不支持直接对主版本config进行操作.";
            logger.error(msg);
            executeResult.setCode(BaseController.REQUEST_ERROR);
            executeResult.setMsg(msg);
            return executeResult;
        }
        Feature existOne = this.featureRepository.findOne(feature.getId());
        if (null == existOne) {
            executeResult = new ExecuteResult();
            executeResult.setCode(StandardFeedBackInfo.REQUEST_ERROR);
            executeResult.setMsg("id指定的feature不存在 id:" + feature.getId());
            return executeResult;
        }
        final String existsReqId = existOne.getReqId();
        if((!"-1".equals(existsReqId)) && (null != existsReqId) && (!reqId.equals(existsReqId))){
            executeResult.setCode(BaseController.REQUEST_ERROR);
            executeResult.setMsg("feature被其它req占用, reqId:" + existsReqId);
            return executeResult;
        }
        //TODO
//        IndexingId indexingIdFeatureToReq = new IndexingId("feature_req_indexing", existOne.getFeatureId());
//        Indexing featureIndexing = this.indexingService.getIndexing(indexingIdFeatureToReq);
//        if (null != featureIndexing) {
//            Map<String, String> temp = featureIndexing.getIndexMap();
//            if (!CollectionUtils.isEmpty(temp)) {
//                String otherReqId = temp.keySet().iterator().next();
//                if (!reqId.equalsIgnoreCase(otherReqId)) {
//                    executeResult.setCode(BaseController.REQUEST_ERROR);
//                    executeResult.setMsg("feature被其它req占用, reqId:" + otherReqId);
//                    return executeResult;
//                }
//            }
//        }

        String id = existOne.getId();
        FeatureReqId featureReqId = new FeatureReqId();
        featureReqId.setReqId(reqId);
        featureReqId.setFeatureId(id);
        FeatureReq featureReq = this.featureReqRepository.findOne(featureReqId);
        String configId = null == featureReq ? null : featureReq.getAttrConfigId();
        Config config = new Config();
        config.setId(configId);
        Map<String, String> attrs = feature.getAttr();
        //将feature_name放入feature变更
        //req改feature_name并不认为占用了feature
        this.featureOperations.updatePropertiesNotNullById(feature);
        if (null == attrs) {
            executeResult.setCode(BaseController.REQUEST_ERROR);
            executeResult.setMsg("传入的attr为空，放弃操作");
            return executeResult;
        }
        /** attrs为空map时(且不为null)这里会重置feature的config ,解除占用关系*/
        if (CollectionUtils.isEmpty(attrs)) {
            logger.info("empty attrs found, reset(delete) will be executed.");
            if ("ADD".equalsIgnoreCase(existOne.getStatus())){
                executeResult.setCode(BaseController.REQUEST_ERROR);
                executeResult.setMsg("指定feature为该req所创建，feature未发布前不允许解除关联");
                return executeResult;
            }
            //该功能点没有被占用，不用解除占用
            if (existsReqId == null || "-1".equals(existsReqId)){
                return executeResult;
            }
            try {
                IndexingId indexingId = new IndexingId("req_feature_indexing", reqId);
                this.indexingService.remove(indexingId, new String[]{id});
//                this.indexingService.deleteIndex(indexingIdFeatureToReq);
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
                executeResult.setCode(BaseController.REQUEST_ERROR);
                executeResult.setMsg(e.getMessage());
                return executeResult;
            }
            if (!StringUtils.isEmpty(configId)) {
                this.configService.deleteConfigById(configId);
                this.featureReqRepository.delete(featureReqId);

            }
            if ((!"ADD".equalsIgnoreCase(existOne.getStatus())) && (!"ONLINE".equalsIgnoreCase(existOne.getStatus()))) { //将feature状态更新为ONLINE
                Feature update = new Feature();
                update.setId(existOne.getId());
                update.setStatus("ONLINE");
                update.setReqId("-1");
                this.featureOperations.updatePropertiesNotNullById(update);
            }
            return executeResult;
        }

        /** 以下以刷新（delete-rebuild）的方式更新feature config */
        config.setKVMap(attrs);
        config = this.configService.saveConfig(config, false);
        if (StringUtils.isEmpty(configId)) { //如果对应的featureReq不存在，则新建
            configId = config.getId();
            featureReq = new FeatureReq();
            featureReq.setId(featureReqId);
            featureReq.setAttrConfigId(configId);
            this.featureReqRepository.save(featureReq);
        }
        //刷新indexing req_feature
            IndexingId indexingId = new IndexingId("req_feature_indexing", reqId);
            Map<String, String> indexingMap = new HashMap<>();
            String featureName = feature.getFeatureName();
            //TODO feature name是必然有的
        //TODO
        //TODO
//            if (StringUtils.isEmpty(featureName)) {
//                try {
//                    this.featureAutoConfigure(existOne, reqId);
//                } catch (Exception e) {
//                    logger.error(e.getMessage(), e);
//                    executeResult.setCode(BaseController.REQUEST_ERROR);
//                    executeResult.setMsg(e.getMessage());
//                    return executeResult;
//                }
//                featureName = existOne.getFeatureName();
//            }
            indexingMap.put(id, featureName);
            try {
                this.indexingService.indexing(new Indexing(indexingId, indexingMap));
//                Map<String, String> temp = new HashMap<>();
//                temp.put(reqId, reqId);
//                this.indexingService.indexing(new Indexing(indexingIdFeatureToReq, temp));
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
                executeResult.setCode(BaseController.REQUEST_ERROR);
                executeResult.setMsg(e.getMessage());
                return executeResult;
            }
        if ((!"ADD".equalsIgnoreCase(existOne.getStatus()))) { //将feature状态更新为UPDATE
            Feature update = new Feature();
            update.setId(existOne.getId());
            update.setReqId(reqId);
            update.setStatus("UPDATE");
            this.featureOperations.updatePropertiesNotNullById(update);
        }

        return executeResult;
    }


    public ExecuteResult deleteFeature(Feature feature) {
        ExecuteResult executeResult = new ExecuteResult();
        Feature existOne = this.featureRepository.findById(feature.getId());
        if (null == existOne) {
            executeResult.setCode(StandardFeedBackInfo.REQUEST_ERROR);
            executeResult.setMsg("指定参数未找到feature, id:" + feature.getId() + ", reqId:" + feature.getReqId());
            return executeResult;
        }
        if (!StringUtils.isEmpty(existOne.getReqId()) && !Constants.FEATURE_ROOT_REQ_ID.equals(existOne.getReqId()) && !feature.getReqId().equals(existOne.getReqId())) {
            Assert.isTrue(feature.getReqId().equals(existOne.getReqId()), "当前req不是功能点对应的req.req=" + feature.getReqId() + ".dbreq=" + existOne.getReqId());
        }
//        this.featureOperations.updateFeature(feature);
        if ("ADD".equalsIgnoreCase(existOne.getStatus()) || Constants.FEATURE_ROOT_REQ_ID.equals(feature.getReqId())) {
            if (!Constants.FEATURE_ROOT_REQ_ID.equalsIgnoreCase(feature.getReqId())){   //reqId != -1时
                try {
                    this.flushIndexingForFeatureAndReq(existOne, feature.getReqId(), -1);
                } catch (Exception e) {
                    logger.error(e.getMessage(), e);
                    executeResult.setCode(BaseController.REQUEST_ERROR);
                    executeResult.setMsg(e.getMessage());
                    return executeResult;
                }
                FeatureReqId featureReqId = new FeatureReqId();
                featureReqId.setFeatureId(existOne.getId());
                featureReqId.setReqId(feature.getReqId());
                FeatureReq featureReq = featureReqRepository.findOne(featureReqId);
                if (null != featureReq) {
                    configService.deleteConfigById(featureReq.getAttrConfigId());
                    featureReqRepository.delete(featureReqId);
                }
            }
            configService.deleteConfigById(existOne.getAttrConfigId());
            this.featureRepository.delete(existOne.getId());
            existOne.setStatus("DELETE");
            //修改父节点的children
//            Feature parent = this.featureRepository.findByFeatureId(existOne.getParentId());
//            if (null != parent) {
//                parent.getChildren().remove(existOne.getFeatureId());
//                this.featureRepository.save(parent);
//            }
            executeResult.setData(null);
        } else {
            try {
                this.flushIndexingForFeatureAndReq(existOne, feature.getReqId(), 1);
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
                executeResult.setCode(BaseController.REQUEST_ERROR);
                executeResult.setMsg(e.getMessage());
                return executeResult;
            }
            existOne.setStatus("DELETE");
            existOne.setReqId(feature.getReqId());
            this.featureRepository.save(existOne);
            executeResult.setData(existOne);
        }


        return executeResult;
    }



    /**
     * @param feature, 处理indexing表中的两组记录，feature_req_indexing/req_feature_indexing
     * @param optMode -1删除， 1-新增
     */
    private void flushIndexingForFeatureAndReq(Feature feature, String reqId, int optMode) throws Exception {

        if (optMode == 1) {
//            Indexing indexingFeatureToReq = new Indexing();
//            indexingFeatureToReq.setId(new IndexingId(Constants.FEATURE_REQ_INDEX_GROUP, feature.getFeatureId()));
//            Map indexMap1 = new HashMap();
//            indexMap1.put(reqId, reqId);
//            indexingFeatureToReq.setIndexMap(indexMap1);
//            indexingService.indexing(indexingFeatureToReq);


            Indexing indexing = new Indexing();
            IndexingId indexingId = new IndexingId();
            indexingId.setIndexGroup("req_feature_indexing");
            indexingId.setFilterTag(reqId);
            Map<String, String> indexMap = new HashMap<String, String>();
            indexMap.put(feature.getId(), feature.getFeatureName());


            indexing.setIndexMap(indexMap);
            indexing.setId(indexingId);
            this.indexingService.indexing(indexing);

        } else if (optMode == -1) {
//            IndexingId featureReqId = new IndexingId(Constants.FEATURE_REQ_INDEX_GROUP, feature.getFeatureId());
//            this.indexingService.deleteIndex(featureReqId);

            IndexingId indexingId = new IndexingId("req_feature_indexing", reqId);
            this.indexingService.removeIfExists(indexingId, new String[]{feature.getId()});
        }
    }

    /**
     * 这个方法是req为-1时直接修改feature主版本
     * @param feature
     * @return
     */
    public ExecuteResult updateFeature(Feature feature) {
        ExecuteResult executeResult = this.checkUpdateFeature(feature);
        if (!executeResult.isSuccess()) {
            return executeResult;
        }
        Feature existOne = this.featureRepository.findById(feature.getId());
        if (existOne == null) {
            executeResult.setCode(StandardFeedBackInfo.REQUEST_ERROR);
            executeResult.setMsg("id指定的feature不存在, id:" + feature.getId() + ",reqId:" + feature.getReqId());
            return executeResult;
        }
//        if ("add".equalsIgnoreCase(existOne.getFeatureChangeType())) {    //在修改add类型的pag_layout时layoutChangeType是不会改变的
//            feature.setFeatureChangeType(null);
//        }
        if (!CollectionUtils.isEmpty(feature.getAttr())) {
            //TODO
            Config attrConfig = this.configService.saveConfig(existOne.getAttrConfigId(), null, feature.getAttr(), null, null);
            feature.setAttrConfigId(attrConfig.getId());
        }

//        feature.setStatus(Constants.FEATURE_STATUS_ONLINE);
        feature.setStatus(null);
        feature.setReqId(null);
        this.featureOperations.updatePropertiesNotNullById(feature);
        executeResult.setData(feature);
        return executeResult;
    }

    private ExecuteResult checkUpdateFeature(Feature feature) {
        ExecuteResult executeResult = new ExecuteResult();
        if (null != feature.getStatus() && (!"UPDATE".equalsIgnoreCase(feature.getStatus()))) {
            executeResult.setCode(StandardFeedBackInfo.REQUEST_ERROR);
            executeResult.setMsg("非法的status type类型， （update操作）:" + feature.getStatus());
        }
        return executeResult;
    }

    /**
     * 这里的create必定存在对应的
     *
     * @param feature
     * @return
     */
    @Deprecated
    private ExecuteResult createFeature(Feature feature) {
        ExecuteResult executeResult = this.checkCreateFeature(feature);

        Feature master = this.featureRepository.findOne(feature.getId());
        if (null == master) {
            executeResult.setCode(StandardFeedBackInfo.REQUEST_ERROR);
            executeResult.setMsg("no master feature found for id:" + feature.getId());
            return executeResult;
        }
        Config featureAttr = this.configService.saveConfig(null, master.getAttrConfigId(), feature.getAttr(), null, null);
        master.setAttrConfigId(featureAttr.getId());
        master.setId(SeqGenerate.createId("F"));
        master.setStatus(feature.getStatus());
        master.setReqId(feature.getReqId());
        this.featureRepository.save(master);
        try {
            this.flushIndexingForFeatureAndReq(master, feature.getReqId(), 1);
            executeResult.setData(master);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            executeResult.setMsg(e.getMessage());
            executeResult.setCode(StandardFeedBackInfo.REQUEST_ERROR);
        }
        return executeResult;
    }

    private ExecuteResult checkCreateFeature(Feature feature) {
        ExecuteResult executeResult = new ExecuteResult();
        if (null == feature.getStatus()) {
            feature.setStatus("UPDATE");
        }
        if (!("UPDATE".equalsIgnoreCase(feature.getStatus()) || "DEL".equalsIgnoreCase(feature.getStatus()))) {
            executeResult.setCode(StandardFeedBackInfo.REQUEST_ERROR);
            executeResult.setMsg("update/delete操作遭遇非法的status:" + feature.getStatus());
        }
        return executeResult;
    }

    /**
     * 创建一个新的feature
     *
     * @param feature
     * @return
     */
    public ExecuteResult addFeature(Feature feature) {
        ExecuteResult executeResult = this.checkFeatureAdding(feature);
        if (!executeResult.isSuccess()) {
            return executeResult;
        }

        if (StringUtils.isEmpty(feature.getReqId()) || Constants.FEATURE_ROOT_REQ_ID.equals(feature.getReqId())) {
            feature.setReqId(Constants.FEATURE_ROOT_REQ_ID);
            feature.setStatus(Constants.FEATURE_STATUS_ONLINE);
        } else {
            feature.setStatus(Constants.FEATURE_STATUS_ADD);
        }
        feature.setId(SeqGenerate.createId(IdTag.FEATURE_ID));

        //TODO 不再处理path
//        if ((!StringUtils.isEmpty(feature.getFeatureName())) && StringUtils.isEmpty(feature.getPath())) {
//            //根据parent处理path
//            String path = StringUtils.isEmpty(parent.getPath()) ? "" : parent.getPath() + "/";
//            path = path + feature.getFeatureName();
//            feature.setPath(path);
//        }
        Map<String, String> configIdMap = new HashMap<>();
//        feature.getAttr().put("feature_name",feature.getFeatureName());
        try {
            //创建对应的attr_config，这个config可能是没有map的
            configIdMap = this.generateConfigForFeature(feature.getAttr(), feature.getReqId());
            feature.setAttrConfigId(configIdMap.get("master"));
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            executeResult.setCode(StandardFeedBackInfo.REQUEST_ERROR);
            executeResult.setMsg(e.getMessage());
            return executeResult;
        }
        this.featureRepository.save(feature);
        if (!Constants.FEATURE_ROOT_REQ_ID.equals(feature.getReqId())) {
            //新增req feature config 记录
            FeatureReqId featureReqId = new FeatureReqId();
            featureReqId.setReqId(feature.getReqId());
            featureReqId.setFeatureId(feature.getId());
            FeatureReq featureReq = new FeatureReq();
            featureReq.setId(featureReqId);
            featureReq.setAttrConfigId(configIdMap.get("req"));
            featureReqRepository.save(featureReq);
            //新增功能点占用关系
            try {
                this.flushIndexingForFeatureAndReq(feature, feature.getReqId(), 1);
            } catch (Exception e) {
                logger.error("com.winit.feature.manager.FeatureManager.addFeature 修改功能点占用异常", e);
            }
        }

        executeResult.setData(feature);
        return executeResult;
    }

    /**
     * 新增功能点时 创建两个config map
     *
     * @param changeConfig
     * @return
     * @throws Exception
     */
    private Map generateConfigForFeature(Map<String, String> changeConfig, String reqId) throws Exception {
        Map map = new HashMap();
        Config attrConfig = new Config();
        attrConfig.setKVMap(new HashMap<String, String>());
        if (!CollectionUtils.isEmpty(changeConfig)) {
            attrConfig.getKVMap().putAll(changeConfig);
        }
        Config newAttrConfig = this.configService.saveConfig(attrConfig);
        map.put("master", newAttrConfig.getId());
        if (!Constants.FEATURE_ROOT_REQ_ID.equals(reqId)) {
            attrConfig.setParentId(newAttrConfig.getId());
            Config reqConfig = this.configService.saveConfig(attrConfig);
            map.put("req", reqConfig.getId());
        }
        return map;
    }

//    private void addFeatureChilds(Feature parent, String featureId, int location) {
//        List<String> layoutChildren = parent.getChildren();
//        if (null == layoutChildren) {
//            layoutChildren = new ArrayList<>();
//            parent.setChildren(layoutChildren);
//            layoutChildren.add(featureId);
//        } else {
//            layoutChildren.add(featureId);
//        }
//    }

    private ExecuteResult checkFeatureAdding(Feature feature) {
        ExecuteResult executeResult = new ExecuteResult();
//        if (feature.getId() == null && feature.getLocationInParent() == null) {
//            executeResult.setCode(StandardFeedBackInfo.REQUEST_ERROR);
//            executeResult.setMsg("locationInParent不能为null");
//        }
        if (null != feature.getStatus() && (!"ADD".equalsIgnoreCase(feature.getStatus()))) {
            executeResult.setCode(StandardFeedBackInfo.REQUEST_ERROR);
            executeResult.setMsg("add操作遭遇非法status" + feature.getStatus());
        }
//        if (null == feature.getParentId()) {
//            executeResult.setCode(StandardFeedBackInfo.REQUEST_ERROR);
//            executeResult.setMsg("add操作缺少parentId");
//        }
        return executeResult;
    }

    public ExecuteResult getFeature(Integer withChildren, String featureSys, String featureId, String reqId, boolean withAttrs) {
        return this.getFeature(withChildren, featureSys, featureId, reqId, withAttrs, null);
    }

    public ExecuteResult getFeature(Integer withChildren, String featureSys, String featureId, String reqId, boolean withAttrs, String changTypeExclude) {
        logger.info("com.winit.feature.manager.FeatureManager.getFeature start");
        ExecuteResult result = new ExecuteResult();
        List<Feature> rootFeatures = null;
//        String parentId = null;
//        if (StringUtils.isEmpty(featureSys)){
//
//        }
//        if (StringUtils.isEmpty(featureId)) {    //未指定featureId则查顶级feature，即parentId为-1
//            if (!StringUtils.isEmpty(featureSys)) {
//                parentId = "0";
//            } else {
//                parentId = "-1";
//            }
//        }
        //TODO ?
        rootFeatures = this.featureOperations.findAllByFeatureSysAndId(null, featureSys, featureId, changTypeExclude);
        if (CollectionUtils.isEmpty(rootFeatures)) {
            result.setCode(StandardFeedBackInfo.REQUEST_ERROR);
            result.setMsg("指定参数的feature不存在");
            return result;
        }
//        if ("-1".equalsIgnoreCase(parentId)) {
//            Feature root = rootFeatures.get(0);
//            rootFeatures = new ArrayList<>();
//            List<String> childIds = root.getChildren();
//            for (String childId : childIds) {
//                List<Feature> temp = this.featureOperations.findAllByFeatureParentIdAndFeatureSysAndFeatureId(root.getFeatureId(), null, childId, null);
//                if (!CollectionUtils.isEmpty(temp)) {
//                    rootFeatures.addAll(temp);
//                }
//            }
//        }

        List<Indexing> indexList = indexingService.getFilterTagMap(Constants.FEATURE_REQ_INDEX_GROUP);

        List rsObjs = new ArrayList<>();
        result.setData(rsObjs);
//        if (rootFeatures.size() > 1 && "0".equalsIgnoreCase(rootFeatures.get(0).getParentId())) {
//            result.setCode(StandardFeedBackInfo.REQUEST_ERROR);
//            result.setMsg("error occurred in sys base, more than one feature root found");
//            return result;
//        }
        for (Feature feature : rootFeatures) {
            if ("ADD".equalsIgnoreCase(feature.getStatus()) && ("-1".equalsIgnoreCase(reqId) || null == reqId)) {
                continue;
            }
            try {
                if (withChildren.intValue() == 1) {
                    rsObjs.add(this.getFeature(feature, reqId, indexList, withAttrs, changTypeExclude));
                } else if (withChildren.intValue() == 0) {
                    if (withAttrs) {
                        this.featureAutoConfigure(feature, reqId);
                    }
//                    feature.setFeatureName(feature.getAttr().get("feature_name"));
                    BaseTree baseTree = TreeUtil.getTree(feature);
//                    baseTree.setStatus(getFeatureStatus(feature.getFeatureId(), reqId, indexList));
                    rsObjs.add(baseTree);
                }
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
                result.setCode(StandardFeedBackInfo.REQUEST_ERROR);
                result.setMsg(e.getMessage());
                break;

            }
        }
        logger.info("com.winit.feature.manager.FeatureManager.getFeature end");
        return result;
    }


    private BaseTree getFeature(Feature feature, String reqId, List<Indexing> list, boolean withAttrs, String changeTypeExclude) throws Exception {
        if (withAttrs) {
            this.featureAutoConfigure(feature, reqId);
        }
//        feature.setFeatureName(feature.getAttr().get("feature_name"));
        BaseTree baseTree = TreeUtil.getTree(feature);
//        baseTree.setStatus(getFeatureStatus(feature.getFeatureId(), reqId, list));
        List<BaseTree> childrenBaseTree = new ArrayList<>();
        baseTree.setChildren(childrenBaseTree);
        //set config
//        List<String> children = feature.getChildren();
//        if (CollectionUtils.isEmpty(children)) {
//            return baseTree;
//        }
//        for (String childName : children) {
//            List<Feature> childs = this.featureOperations.findAllByFeatureParentIdAndFeatureSysAndFeatureId(feature.getFeatureId(), feature.getSys(), childName, changeTypeExclude);
//            if (CollectionUtils.isEmpty(childs)) {
//                logger.info("指定feature_id的feature未找到，feature_id:" + childName);
//                continue;
//            }
//            if ("ADD".equalsIgnoreCase(childs.get(0).getStatus()) && ("-1".equalsIgnoreCase(reqId) || null == reqId)) {
//                continue;
//            }
//            childrenBaseTree.add(this.getFeature(childs.get(0), reqId, list, withAttrs, changeTypeExclude));
//        }
        return baseTree;
    }

    //判断功能点是否被req占用，如果被占用，返回哪个reqid
    private String getFeatureStatus(String featureId, String reqId, List<Indexing> list) {
        if (list.size() == 0) {
            return null;
        }
        String status = null;
        for (Indexing index : list) {
            if (index.getId().getFilterTag().equalsIgnoreCase(featureId)) {
                if (index.getIndexMap().containsKey(reqId)) {
                    status = "self-relate";
                } else {
                    status = "other-relate";
                }
                break;
            }
        }
        return status;
    }

    /**
     * 取出feature的config attr
     * @param feature
     * @param reqId
     * @throws Exception
     */
    private void featureAutoConfigure(Feature feature, String reqId) throws Exception {
        Map<String, String> attr = null;
        String attrConfigId = feature.getAttrConfigId();
        if (!StringUtils.isEmpty(attrConfigId)) {
            Config attrConfig = this.configService.getConfigMap(attrConfigId, false);
            if (null != attrConfig) {
                attr = attrConfig.getKVMap();
            }
        }
        if (StringUtils.isEmpty(reqId) || "-1".equalsIgnoreCase(reqId)) {
            feature.setAttr(attr);
            return;
        }
        FeatureReqId id = new FeatureReqId();
        id.setFeatureId(feature.getId());
        id.setReqId(reqId);
        FeatureReq featureReq = this.featureReqRepository.findOne(id);
        if (null != featureReq) {
            String configId = featureReq.getAttrConfigId();
            if (!StringUtils.isEmpty(configId)) {
                Config reqAttrConfig = this.configService.getConfigMap(configId, false);
                if (reqAttrConfig != null) {
                    Map<String, String> temp = reqAttrConfig.getKVMap();
                    if (!CollectionUtils.isEmpty(temp)) {
                        if (null == attr) {
                            attr = temp;
                        } else {
                            attr.putAll(temp);
                        }
                    }
                }
            }
        }
        if (!CollectionUtils.isEmpty(attr)) {
//            feature.setFeatureName(attr.get("feature_name"));
        }
        feature.setAttr(attr);
    }

    public ExecuteResult operateFeaturesForReqOnline(List<String> reqIds) {
        ExecuteResult rs = null;
        for (String reqId : reqIds) {
            rs = this.operateFeaturesForReqOnline(reqId);
            if (!rs.isSuccess()) {
                return rs;
            }
        }
        return rs;
    }


    public ExecuteResult operateFeaturesForReqOnline(String reqId) {
        ExecuteResult rs = new ExecuteResult();
        IndexingId indexingId = new IndexingId("req_feature_indexing", reqId);
        Indexing indexing = this.indexingService.getIndexing(indexingId);
        if (null == indexing) {
            rs = ExecuteResult.successExecuteResult(Object.class);
            return rs;
        }
        Map<String, String> relateFeatures = indexing.getIndexMap();
        if (CollectionUtils.isEmpty(relateFeatures)) {
            rs = ExecuteResult.successExecuteResult(Object.class);
            return rs;
        }
        for (String id : relateFeatures.keySet()) {
            try {
                this.operateFeatureForReqOnline(id, reqId);
            } catch (Exception e) {
                logger.error(e.getMessage());
                rs.setCode(BaseController.REQUEST_ERROR);
                rs.setMsg(e.getMessage());
                return rs;
            }
        }
        return rs;
    }

    private ExecuteResult operateFeatureForReqOnline(String id, String reqId) throws Exception {
        ExecuteResult executeResult = new ExecuteResult();
        Feature feature = this.featureRepository.findByFeatureId(id);
        if (feature.getReqId() == null) {
            return executeResult;
        }
        if ((!reqId.equalsIgnoreCase(feature.getReqId())) && (null != feature.getReqId()) && (!"-1".equalsIgnoreCase(feature.getReqId()))) {
//            String msg = "data error between req_feature_indexing and feature, reqId" + reqId;
            String msg = "数据错误, feature中的reqId与indexing中的req_feature_indexing中的记录不匹配" + reqId;
            logger.error(msg);
            executeResult.setCode(BaseController.REQUEST_ERROR);
            executeResult.setMsg(msg);
            return executeResult;
        }
        if ("DEL".equalsIgnoreCase(feature.getStatus()) && reqId.equalsIgnoreCase(feature.getReqId())) { //标记删除的直接删除
            this.featureRepository.delete(id);
//            this.indexingService.deleteIndex(new IndexingId("feature_req_indexing", featureId));
            return executeResult;
        }
        FeatureReqId featureReqId = new FeatureReqId(id, reqId);

        /** 合并feature config */
        FeatureReq featureReq = this.featureReqRepository.findOne(featureReqId);
        if (null != featureReq) {
            this.configService.mergeConfigById(featureReq.getAttrConfigId(), feature.getAttrConfigId(), true);
        }
//        this.indexingService.deleteIndex(new IndexingId("feature_req_indexing", id));
        Feature update = new Feature();
        update.setId(feature.getId());
        update.setReqId("-1");
        update.setStatus("ONLINE");
        this.featureOperations.updatePropertiesNotNullById(update);
        return executeResult;
    }

    /**
     * 解除关联后重置功能点信息
     *
     * @param featureId
     * @return
     */
    public Map initFeature(String featureId) {
        Map map = new HashMap<>();
        if (StringUtils.isEmpty(featureId)) {
            logger.info("com.winit.feature.manager.FeatureManager.initFeature featureId为空");
            map.put("code","1");
            map.put("desc","重置功能点信息,功能点id为空");
            return map;
        }

        Feature feature = featureRepository.findByFeatureId(featureId);
        if (null == feature) {
            logger.info("com.winit.feature.manager.FeatureManager.initFeature feature为null featureId=" + featureId);
            map.put("code","1");
            map.put("desc","重置功能点信息,根据功能点id查询功能点为空");
            return map;
        }

        if (Constants.FEATURE_ROOT_REQ_ID.equals(feature.getReqId())) {
            logger.info("com.winit.feature.manager.FeatureManager.initFeature feature当前为线上版本,不需要解除关联 featureId=" + featureId);
            map.put("code","1");
            map.put("desc","重置功能点信息,当前功能点为线上版本,不需要解除关联");
            return map;
        }
        map.put("code","0");
        map.put("desc","");
        // 2017-12-07新增对indexing表中req->feature关系的处理
        try {
            this.flushIndexingForFeatureAndReq(feature, feature.getReqId(), -1);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            map.put("code","1");
            map.put("desc","数据错误，indexing中feature的关联关系错误");
            return map;
        }
//        IndexingId indexingId = null;
//        try {
//            indexingId = new IndexingId("req_feature_indexing", feature.getReqId());
//            if(this.indexingService.getIndexing(indexingId) != null) {
//                this.indexingService.remove(indexingId, new String[]{featureId});
//            }
//        } catch (Exception e) {
//            logger.error(e.getMessage(), e);
//            map.put("code","0");
//            map.put("desc", "数据错误，indexing中feature的关联关系错误");
//            return map;
//        }
//        indexingId = new IndexingId("feature_req_indexing", featureId);
//        this.indexingService.deleteIndex(indexingId);


        Map<String,Boolean> data = new HashMap<>();
        //删除req和功能点关联关系
        FeatureReqId featureReqId = new FeatureReqId();
        featureReqId.setFeatureId(featureId);
        featureReqId.setReqId(feature.getReqId());
        FeatureReq featureReq = featureReqRepository.findOne(featureReqId);
        if (null != featureReq) {

            featureReqRepository.delete(featureReq);
            //删除req修改功能点信息config
            configService.deleteConfigById(featureReq.getAttrConfigId());
        }


        //修改功能点信息 如果功能点为新增功能点，则直接删除，否则只是修改功能点的状态
        if(Constants.FEATURE_STATUS_ADD.equals(feature.getStatus())){
            featureRepository.delete(feature);
            data.put("isDel",true);
        }else {
            feature.setStatus(Constants.FEATURE_STATUS_ONLINE);
            feature.setReqId(Constants.FEATURE_ROOT_REQ_ID);
            featureRepository.save(feature);
            data.put("isDel",false);
        }
        map.put("data",data);
        return map;
    }
}
